package org.hzz.application.handler.user;

import io.gitee.pkmer.convention.converter.TargetAndSourceConverter;
import io.gitee.pkmer.convention.page.PageResponse;
import io.gitee.pkmer.designpattern.strategy.AbstractExecuteStrategy;
import lombok.Setter;
import org.hzz.application.command.user.ShowCouponCmd;
import org.hzz.promotions.domain.entity.CouponEntity;
import org.hzz.promotions.domain.service.CouponDomainService;
import org.hzz.promotions.domain.service.UserCouponDomainService;
import org.hzz.promotions.domain.valueobject.CouponReceive;
import org.hzz.promotions.types.vo.ShowCouponVo;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author <a href="mailto:1193094618@qq.com">pkmer</a>
 * <br>
 * <a href = "https://gitee.com/developeros/videos-online">Code Repository</a>
 * At 2024/9/2
 */
@Component
public class ShowCouponCmdHandler
        implements AbstractExecuteStrategy<ShowCouponCmd, PageResponse<ShowCouponVo>> {

    @Setter(onMethod_ = @Autowired)
    private CouponDomainService couponDomainService;

    @Setter(onMethod_ = @Autowired)
    private UserCouponDomainService userCouponDomainService;
    @Override
    public String mark() {
        return ShowCouponCmd.MARK;
    }

    @Override
    public PageResponse<ShowCouponVo> executeWithResp(ShowCouponCmd cmd) {
        PageResponse<CouponEntity> pages = couponDomainService.pageQueryCoupon(cmd.getPageQuery());
        PageResponse<ShowCouponVo> results = Converter.INSTANCE.convertToTargetPage(pages);

        List<Long> couponIds = pages.getList().stream().map(CouponEntity::getId).toList();

        Map<Long, CouponReceive> userCouponMap = userCouponDomainService.userReceiveCouponNum(cmd.getUserId(), couponIds);


        for(int i = 0; i < pages.getList().size(); i++){
            CouponEntity coupon = pages.getList().get(i);
            ShowCouponVo vo = results.getList().get(i);

            CouponReceive couponReceive = userCouponMap.computeIfAbsent(coupon.getId(), CouponReceive::new);
            /**
             * 是否可以领取：也就是优惠券还有剩余并且用户已领取数量未超过限领数量。
             * 如果为false，展示为已抢完
             */
            if(coupon.getTotalNum() >= coupon.getIssueNum()
                && couponReceive.getCount() <= coupon.getUserLimit()){
                vo.setAvaiable(true);
            }

            /**
             * 是否已经领取：也就是用户是否有已经领取，尚未使用的券。
             * 如果有，则显示为去使用
             */
            vo.setRecevied(couponReceive.getCount() > 0);
        }
        return results;
    }

    @Mapper
    interface Converter extends TargetAndSourceConverter<ShowCouponVo,CouponEntity>{
        Converter INSTANCE = Mappers.getMapper(Converter.class);
    }
}
